﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mbs.ComponentModel.Container;
using Mbs.ComponentModel.Container.Fluent;
using NUnit.Framework;
using AspectSharp;

namespace Mbs.AOP.Test
{
    [TestFixture]
    public class AOPTest
    {
        private IKernel kernel;

       [SetUp]
        public void Init()
        {
            kernel = new Kernel();
        }

       [Test]
       public void InterceptAll()
       {
           string content = @"  import Mbs.AOP.Test in Mbs.AOP.Test
       
			                                    aspect MyAspect for ComplexClass
                                              
				                                        pointcut method|property(*)
				                                            advice(LogInterceptor)
				                                        end
                                             
			                                    end";

           WrapAndInvokeEverything(content);
       }

       [Test]
       public void InterceptAllMethods()
       {
           string content = @"  import Mbs.AOP.Test in Mbs.AOP.Test
       
			                                    aspect MyAspect for ComplexClass
                                              
				                                        pointcut method(*)
				                                            advice(LogInterceptor)
				                                        end
                                             
			                                    end";

           WrapAndInvokeEverything(content);
       }

       [Test]
       public void InterceptAllProperties()
       {
           string content = @"  import Mbs.AOP.Test in Mbs.AOP.Test
       
			                                    aspect MyAspect for ComplexClass
                                              
				                                        pointcut property(*)
				                                            advice(LogInterceptor)
				                                        end
                                             
			                                    end";

           WrapAndInvokeEverything(content);
       }

       [Test]
       public void InterceptAllGetProperties()
       {
           string content = @"  import Mbs.AOP.Test in Mbs.AOP.Test
       
			                                    aspect MyAspect for ComplexClass
                                              
				                                        pointcut propertyread(*)
				                                            advice(LogInterceptor)
				                                        end
                                             
			                                    end";

           WrapAndInvokeEverything(content);
       }

       [Test]
       public void InterceptAllPropertyWrite()
       {
           string content = @"  import Mbs.AOP.Test in Mbs.AOP.Test
       
			                                    aspect MyAspect for ComplexClass
                                              
				                                        pointcut propertywrite(*)
				                                            advice(LogInterceptor)
				                                        end
                                             
			                                    end";

           WrapAndInvokeEverything(content);
       }

       //[Test]
       //public void InterceptByXmlConfig()
       //{
       //    var builder = new AspectXmlEngineBuilder("AspectSharp.xml");
       //    InternalExecute(builder);
       //}

       private  void WrapAndInvokeEverything(string content)
       {
           var builder = new AspectSharp.Builder.AspectLanguageEngineBuilder(content);

           InternalExecute(builder);
       }

       private void InternalExecute(AspectSharp.Builder.IAspectEngineBuilder builder)
       {
           kernel.Register(f => f.Bind<IAspectEngine>().Factory(ctx => builder.Build()));
           kernel.Register(f => f.To<AOPKernelListner>());
           kernel.ListnerManager.Register(kernel.Get<AOPKernelListner>());

           kernel.Register(f => f.Bind<ComplexClass>().To<ComplexClass>());

           ComplexClass instance = kernel.Get<ComplexClass>();
           instance.DoNothing();
           instance.DoSomething();
           int arg = 1;

           instance.DoSomething(arg);
           instance.DoSomething(arg, "hiya");

           instance.Name = "John Johnson";
           Assert.AreEqual("John Johnson", instance.Name);
           instance.Started = true;
           Assert.IsTrue(instance.Started);
       }
    }
}
